package com.tanhua.service;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.tanhua.api.db.UserApi;
import com.tanhua.api.db.UserInfoApi;
import com.tanhua.db.User;
import com.tanhua.db.UserInfo;
import com.tanhua.template.AipFaceTemplate;
import com.tanhua.template.OssTemplate;
import com.tanhua.template.SmsTemplate;

import com.tanhua.utils.JwtUtil;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;


import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author: cfl
 * @CreateTime: 2021-06-18 20:15
 * @Description: 业务逻辑服务
 */
@Service
public class UserService {

    @Reference
    private UserApi userApi;

    @Reference
    private UserInfoApi userInfoApi;

    @Autowired
    private SmsTemplate smsTemplate;  // 发送短信

    @Autowired
    private AipFaceTemplate aipFaceTemplate; // 人脸识别

    @Autowired
    private OssTemplate ossTemplate;  // 图片上传存储

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * @Description: 根据用户手机号查询用户
     */
    public ResponseEntity findByPhone(String phone) {
        User user = userApi.findByPhone(phone);
        return ResponseEntity.ok(user);
    }

    /**
     * @Description: 保存用户
     */
    public ResponseEntity saveUser(User user) {
        Long userId = userApi.saveUser(user);
        return ResponseEntity.ok(userId);
    }

    /**
     * @Description: 发送短信验证码
     */
    public ResponseEntity login(String phone) {
        // 获取6位随机数 使用hutool的RandomUtil工具
        //String code = RandomUtil.randomNumbers(6);

        // 暂时 写定验证码 便于开发
        String code = "123456";
        System.out.println("发送的验证码是："+code);

        // 调用阿里云工具类抽成的启动器模板  【发送手机验证码】
        //smsTemplate.sendSms(phone, code);
        // 放入redis中 （设置过期时间）
        stringRedisTemplate.opsForValue().set("SMS_CODE_" + phone, code, 10, TimeUnit.MINUTES);
        // 返回为空
        return ResponseEntity.ok(null);
    }

    /**
     * @Description: 用户登陆验证判断
     */
    public ResponseEntity loginVerification(String phone, String vCode) {
        // 从redis中获取 短信验证码
        String redisCode = stringRedisTemplate.opsForValue().get("SMS_CODE_" + phone);
        System.out.println("redisCode = " + redisCode);
        // hutool 工具  判断用户输入的 可 redis中存储发验证码 是否一致
        if (!StrUtil.equals(vCode, redisCode)) {
            return ResponseEntity.status(500).body("验证码错误");
        }

        // [优化验证码：用完即删] 到这步说明验证码正确，所有可以删除redis保存的验证码
        stringRedisTemplate.delete("SMS_CODE_" + phone);
        // 一致根据手机号去查询 user信息
        User user = userApi.findByPhone(phone);
        // 用户验证标记 【先默认为老用户】
        boolean isNewUSer = false;
        // 没查到 user ，则修改标记为true 是新用户 --》进行用户注册账户保存
        if (user == null) {
            user = new User();
            user.setPhone(phone);
            // 模拟密码 hutool工具 md5加密
            user.setPassword(SecureUtil.md5("123456"));
            // mybatisPlus 实现了主键回填
            Long userId = userApi.saveUser(user);
            // 把 tb_user 的 id 返回  复制到 user属性
            user.setId(userId);
            isNewUSer = true;
        }
        System.out.println("user = " + user);
        System.out.println("isNewUSer = " + isNewUSer);

        // 将用户的手机号 加密生成字符串 --> token令牌 【JWT工具】
        String token = JwtUtil.createToken(user.getPhone(), "tanhua");
        // 把当前 新用户的信息 转正json格式 存储到redis中
        String user_json = JSON.toJSONString(user);
        // 存到redis中  key:token  value:user_json  并设置1天的过期时间
        stringRedisTemplate.opsForValue().set("TOKEN_"+token,user_json,1,TimeUnit.DAYS);

        // 返回前端需要的 token 和 isNew 的json数据
        Map<String,Object> result = new HashMap<>();
        result.put("token", token);
        result.put("isNew", isNewUSer);
        return ResponseEntity.ok(result);
    }

   /**
    * @Description: 完善用户基本信息
    */
    public ResponseEntity loginReginfo(UserInfo userInfo, String token) {
        // 根据token 获取redis的当前用户 的json数据
        User user = findUserByToken(token);
        // 将 当前的用户的id 赋值 给 userInfo 的id [外键约束，一一对应]
        userInfo.setId(user.getId());
        // 保存用户的基本信息
        userInfoApi.saveUserInfo(userInfo);
        return ResponseEntity.ok(null);
    }

    private User findUserByToken(String token) {
        String user_json = stringRedisTemplate.opsForValue().get("TOKEN_" + token);
        User user = JSON.parseObject(user_json,User.class);
        return user;
    }

    /**
     * @Description: 完善用户头像信息
     */
    public ResponseEntity headPicInfo(MultipartFile headPhoto, String token) throws IOException {
        // 人脸识别
        boolean flag = aipFaceTemplate.detect(headPhoto.getBytes());
        // 识别错误 返回错误结果
        if(flag==false){
            return ResponseEntity.status(500).body("人脸识别错误");
        }
        // 传递图片到oss
        String url = ossTemplate.upload(headPhoto.getOriginalFilename(),
                headPhoto.getInputStream());
        // 根据 token --》当前用户  --》 得到主键 id
        User user = findUserByToken(token);
        // 根据id 修改 图片url
        UserInfo userInfo = new UserInfo();
        userInfo.setId(user.getId());
        userInfo.setAvatar(url);  // 头像img url
        userInfo.setCoverPic(url); // 小视频img url

        // 跟新userInfo --》tb_user_info
        userInfoApi.updateUserInfo(userInfo);  //动态拦截MetaObjectHandler  动态sql为null默认不修改
        return ResponseEntity.ok(null);
    }

}
